package com.feilong.taglib.common.navigation;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.commons.core.util.Validator;
import com.feilong.servlet.http.RequestUtil;
import com.feilong.taglib.base.AbstractCommonTag;
import com.feilong.tools.velocity.VelocityUtil;

/**
 * 飞龙面包屑标签.
 * 
 * @author 金鑫 2010-6-8 上午05:50:38
 */
public class FeiLongSiteMapTag extends AbstractCommonTag{

	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= 1L;

	/** The Constant log. */
	private static final Logger	log					= LoggerFactory.getLogger(FeiLongSiteMapTag.class);

	/** 连接符. */
	private String				connector			= ">";

	/**
	 * 当前路径,默认RequestUtil.getOriginatingServletPath(request)
	 */
	private String				currentPath;

	/** siteMapEntityList,用户所有可以访问的菜单url List. */
	private List<SiteMapEntity>	siteMapEntityList;

	/**
	 * 实现自定义站点地图数据提供程序的途径.
	 * 
	 * @return the object
	 */
	// private String siteMapProvider;
	@Override
	protected Object writeContent(){
		// ConfigurationManager configurationManager = new ConfigurationManager(this.pageContext.getServletContext());
		// String xmlString = configurationManager.getSiteMapXmlPath(siteMapProvider);
		// SiteMapConfigure siteMapConfigure = new SiteMapConfigure(xmlString);
		// return siteMapConfigure.getSiteMapContent("index.jsp");
		HttpServletRequest request = getHttpServletRequest();
		log.info("request.getRequestURI():{}", request.getRequestURI());
		if (Validator.isNull(currentPath)){
			currentPath = RequestUtil.getOriginatingServletPath(request);
		}
		log.info("urlPathHelper.getLookupPathForRequest(request):{}", currentPath);
		List<SiteMapEntity> allParentSiteMapEntityList = getAllParentSiteMapEntityList(currentPath, siteMapEntityList);
		Map<String, Object> contextKeyValues = new HashMap<String, Object>();
		contextKeyValues.put("siteMapEntityList", allParentSiteMapEntityList);
		contextKeyValues.put("connector", connector);
		contextKeyValues.put("request", request);
		String siteMapString = VelocityUtil.parseVMTemplateWithClasspathResourceLoader("/velocity/sitemap.vm", contextKeyValues);
		log.debug("siteMapString is:{}", siteMapString);
		if (Validator.isNull(siteMapString)){
			return "";
		}
		return siteMapString;
	}

	/**
	 * 按照父子关系排序好的 list.
	 * 
	 * @param currentPath
	 *            the current path
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the all parent site map entity list
	 */
	public List<SiteMapEntity> getAllParentSiteMapEntityList(String currentPath,List<SiteMapEntity> siteMapEntities){
		log.info("currentPath:{}", currentPath);
		SiteMapEntity siteMapEntity_in = getSiteMapEntityByPath(currentPath, siteMapEntities);
		return getAllParentSiteMapEntityList(siteMapEntity_in, siteMapEntities);
	}

	/**
	 * 按照父子关系排序好的 list.
	 * 
	 * @param siteMapEntity_in
	 *            the site map entity_in
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the all parent site map entity list
	 */
	public List<SiteMapEntity> getAllParentSiteMapEntityList(SiteMapEntity siteMapEntity_in,List<SiteMapEntity> siteMapEntities){
		if (null == siteMapEntity_in){
			return null;
		}
		// 每次成一个新的
		List<SiteMapEntity> allParentSiteMapEntityList = new LinkedList<SiteMapEntity>();
		constructParentSiteMapEntityList(siteMapEntity_in, siteMapEntities, allParentSiteMapEntityList);
		log.info("before Collections.reverse,allParentSiteMapEntityList size:{}", allParentSiteMapEntityList.size());
		// for (SiteMapEntity sme : allParentSiteMapEntityList){
		// log.info(sme.getName());
		// }
		// 反转
		Collections.reverse(allParentSiteMapEntityList);
		// log.info("after Collections.reverse");
		// for (SiteMapEntity sme : allParentSiteMapEntityList){
		// log.info(sme.getName());
		// }
		return allParentSiteMapEntityList;
	}

	/**
	 * 通过当前的SiteMapEntity,查找到所有的父节点<br>
	 * 递归生成.
	 * 
	 * @param siteMapEntity_in
	 *            the site map entity_in
	 * @param siteMapEntities
	 *            the site map entities
	 * @param allParentSiteMapEntityList
	 *            the all parent site map entity list
	 */
	private void constructParentSiteMapEntityList(
			SiteMapEntity siteMapEntity_in,
			List<SiteMapEntity> siteMapEntities,
			List<SiteMapEntity> allParentSiteMapEntityList){
		// 加入到链式表
		allParentSiteMapEntityList.add(siteMapEntity_in);
		Number parentId = siteMapEntity_in.getParentId();
		// 标识 是否找到parent node
		SiteMapEntity siteMapEntity_parent = null;
		// ****************************************************
		for (SiteMapEntity loopSiteMapEntity : siteMapEntities){
			// 当前的id和传入的siteMapEntity equals
			if (loopSiteMapEntity.getId().equals(parentId)){
				log.info("loopSiteMapEntity.getId():{},siteMapEntity_in.getParentId():{}", loopSiteMapEntity.getId(), parentId);
				siteMapEntity_parent = loopSiteMapEntity;
				break;
			}
		}
		if (null != siteMapEntity_parent){
			// 递归
			constructParentSiteMapEntityList(siteMapEntity_parent, siteMapEntities, allParentSiteMapEntityList);
		}
	}

	/**
	 * 匹配路径.
	 * 
	 * @param currentPath
	 *            the current path
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the site map entity by path
	 */
	public SiteMapEntity getSiteMapEntityByPath(String currentPath,List<SiteMapEntity> siteMapEntities){
		boolean flag = false;
		SiteMapEntity siteMapEntity_return = null;
		for (SiteMapEntity siteMapEntity : siteMapEntities){
			if (siteMapEntity.getRequestMapping().equals(currentPath)){
				flag = true;
				siteMapEntity_return = siteMapEntity;
				break;
			}
		}
		if (!flag){
			log.warn("currentPath is :{},can't find match SiteMapEntity", currentPath);
		}
		return siteMapEntity_return;
	}

	/**
	 * Sets the 连接符.
	 * 
	 * @param connector
	 *            the new 连接符
	 */
	public void setConnector(String connector){
		this.connector = connector;
	}

	/**
	 * Sets the siteMapEntityList,用户所有可以访问的菜单url List.
	 * 
	 * @param siteMapEntityList
	 *            the new siteMapEntityList,用户所有可以访问的菜单url List
	 */
	public void setSiteMapEntityList(List<SiteMapEntity> siteMapEntityList){
		this.siteMapEntityList = siteMapEntityList;
	}

	// public void setSiteMapProvider(String siteMapProvider){
	// this.siteMapProvider = siteMapProvider;
	// }
	/**
	 * Sets the 当前路径,默认RequestUtil.
	 * 
	 * @param currentPath
	 *            the new 当前路径,默认RequestUtil
	 */
	public void setCurrentPath(String currentPath){
		this.currentPath = currentPath;
	}
}
